export default class ScanProvider {
    constructor(emitter, analyzer, captureImage, scanPeriod, refractoryPeriod) {
        this.scanPeriod = scanPeriod;
        this.captureImage = captureImage;
        this.refractoryPeriod = refractoryPeriod;
        this._emitter = emitter;
        this._frameCount = 0;
        this._analyzer = analyzer;
        this._lastResult = null;
        this._active = false;
    }

    start() {
        this._active = true;
        requestAnimationFrame(() => this._scan());
    }

    stop() {
        this._active = false;
    }

    scan() {
        return this._analyze(false);
    }

    _analyze(skipDups) {
        let analysis = this._analyzer.analyze();
        if (!analysis) {
            return null;
        }

        let { result, canvas } = analysis;
        if (!result) {
            return null;
        }

        if (skipDups && result === this._lastResult) {
            return null;
        }

        clearTimeout(this.refractoryTimeout);
        this.refractoryTimeout = setTimeout(() => {
            this._lastResult = null;
        }, this.refractoryPeriod);

        let image = this.captureImage ? canvas.toDataURL('image/webp', 0.8) : null;

        this._lastResult = result;

        let payload = { content: result };
        if (image) {
            payload.image = image;
        }

        return payload;
    }

    _scan() {
        if (!this._active) {
            return;
        }

        requestAnimationFrame(() => this._scan());

        if (++this._frameCount !== this.scanPeriod) {
            return;
        } else {
            this._frameCount = 0;
        }

        let result = this._analyze(true);
        if (result) {
            setTimeout(() => {
                this._emitter.emit('scan', result.content, result.image || null);
            }, 0);
        }
    }
}